/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:        http://wiki.pic24.ru/doku.php/en/osa/ref/intro                                  *
 *              http://picosa.narod.ru                                                          *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:       osa.h                                                                           *
 *  Compilers:  HT-PICC STD                                                                     *
 *              HT-PICC18 STD                                                                   *
 *              Microchip C18                                                                   *
 *              Microchip C30                                                                   *
 *                                                                                              *
 *  Version:    90200   (january, 21, 2009)                                                     *
 *                                                                                              *
 *  Programmer: Timofeev Victor                                                                 *
 *  e-mail:     osa@pic24.ru, testerplus@mail.ru                                                *
 *                                                                                              *
 *  Definition: This file contains all prototypes of functions and variables,                   *
 *              data types definitions, system constants.                                       *
 *              This file must be included in all modules that use OSA services.                *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */


#ifndef __OSA__
#define __OSA__

#define __OSAVERSION__          90200

/************************************************************************************************
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************/




/*
 ************************************************************************************************
 *                                                                                              *
 *  Setting compiler constant. This constant used in "osa.c" to make most                       *
 *  efficient code for used compiler.                                                           *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */

//------------------------------------------------------------------------------
#if   defined(__PICC18__)           /* HT-PICC18        */

    #define __OSAPICC18__
    #define __OSA18__

//------------------------------------------------------------------------------
#elif defined(__18CXX)              /* Microchip C18    */

    #define __OSAMCC18__
    #define __OSA18__

//------------------------------------------------------------------------------
#elif defined(__C30__)              /* Microchip C30    */

    #define __OSAMCC30__
    #define __OSA30__

//------------------------------------------------------------------------------
#elif defined(__PCH__)              /* CCS PICC (not supported now) */


    #define __OSACCS18__
    #define __OSA18__

//------------------------------------------------------------------------------
#elif defined(_PIC12)               /* HT-PICC with baserange family  */

    #define __OSAPICC12__
    #define __OSA12__

//------------------------------------------------------------------------------
#else                               /* HT-PICC with midrange family */

    #define __OSAPICC16__
    #define __OSAPICC__
    #define __OSA16__

#endif
//------------------------------------------------------------------------------




#include "OSAcfg.h"         /* This file contains project configuration         */



/*
 ************************************************************************************************
 *                                                                                              *
 * OSA CONFIGURATION                                                                            *
 *                                                                                              *
 ************************************************************************************************
 */

#if defined(OS_ENABLE_ALL)

    //------------------------------------------------------------------------------
    // undef all config constants

    #undef OS_ENABLE_TIMER
    #undef OS_ENABLE_CSEM
    #undef OS_ENABLE_QUEUE	
    #undef OS_ENABLE_SQUEUE	
    #undef OS_ENABLE_DTIMERS
    #undef OS_ENABLE_CRITICAL_SECTION

    //------------------------------------------------------------------------------
    // undef all old style config constants

    #undef OS_TIMER_ENABLE
    #undef OS_CSEM_ENABLE
    #undef OS_QMSG_ENABLE	//^
    #undef OS_QSMSG_ENABLE     	//^
    #undef OS_DTIMERS_ENABLE

    //------------------------------------------------------------------------------
    // define all config constants

    #define OS_ENABLE_CSEM
    #define OS_ENABLE_QUEUE
    #define OS_ENABLE_SQUEUE
    #define OS_ENABLE_DTIMERS
    #define OS_ENABLE_TTIMERS
    #define OS_ENABLE_CRITICAL_SECTION

#endif



/*------------------------------------------*/
/*                                          */
/* (OSA configuration)                      */
/* Redefining old style constants           */
/*                                          */
/*------------------------------------------*/

#ifdef OS_TIMER_ENABLE
#define OS_ENABLE_TIMER     /* Defined when using timers in tasks (OS_Delay     */
                            /* and wait events with timeout)                    */
#endif

#ifdef OS_CSEM_ENABLE
#define OS_ENABLE_CSEM      /* Defined when using counting semaphores           */
#endif

#ifdef OS_QMSG_ENABLE 	    //^
#define OS_ENABLE_QUEUE      /* Defined when using queue of pointer to messages  */
#endif

#ifdef OS_ENABLE_QMSG 	    //^
#define OS_ENABLE_QUEUE      /* Defined when using queue of pointer to messages  */
#endif

#ifdef OS_QSMSG_ENABLE	    //^
#define OS_ENABLE_SQUEUE     /* Defined when using queue of simple messages      */
#endif

#ifdef OS_ENABLE_QSMSG      //^
#define OS_ENABLE_SQUEUE     /* Defined when using queue of simple messages      */
#endif

#ifdef OS_DTIMERS_ENABLE
#define OS_ENABLE_DTIMERS   /* Defined when using dynamic timers                */
#endif


#ifdef OS_QUEUES_IDENTICAL   //^
#define OS_QUEUE_SQUEUE_IDENTICAL  // Defined to reduce code size when both types 
                                   // of queues are used
#endif


//------------------------------------------------------------------------------
// (OSA configuration)
// Set constants for interrupt usage

#ifdef  OS_ENABLE_INT_SERVICE       // Redefining old style constant
#define OS_ENABLE_INT_ALL
#endif

#ifdef OS_ENABLE_INT_ALL

    #define OS_ENABLE_INT_CSEM      /* Enables interrupt services for counting  */
                                    /* semaphores                               */

    #define OS_ENABLE_INT_MSG       /* Enables interrupt services for pointers  */
                                    /* to messages                              */

    #define OS_ENABLE_INT_SMSG      /* Enables interrupt services for simple    */
                                    /* messages                                 */

    #define OS_ENABLE_INT_QUEUE     /* Enables interrupt services for queues of */
                                    /* pointers to messages and simple messages */

#endif



/*
 *------------------------------------------------------------------------------*
 *                                                                              *
 * (OSA configuration)                                                          *
 * Set system constants for timers                                              *
 *                                                                              *
 *------------------------------------------------------------------------------*
 */

#if defined(OS_ENABLE_TIMER)
#define OS_ENABLE_TTIMERS       /* Enables task timers                          */
#endif


#ifdef OS_ENABLE_PTIMERS        /* Redefining old name (ptimer) to new (dtimer) */
    #define OS_ENABLE_DTIMERS
#endif

#if !defined(OS_STIMERS)
    #define OS_STIMERS  0       /* Number of STimers                            */
#endif


/*--------------------------------------------------*/
/*                                                  */
/* Counting number of old style static timers       */
/*                                                  */
/* note:    it is not recommended to use this       */
/*          type of timers. Use STimers instead.    */
/*                                                  */
/*--------------------------------------------------*/

#ifndef OS_TIMERS8                  /* not recommended to use       */
    #define OS_TIMERS8 0
#endif

#ifndef OS_TIMERS16                 /* not recommended to use       */
    #define OS_TIMERS16 0
#endif

#ifndef OS_TIMERS24                 /* not recommended to use       */
    #define OS_TIMERS24 0
#endif

#ifndef OS_TIMERS32                 /* not recommended to use       */
    #define OS_TIMERS32 0
#endif


#define _OS_TIMER8_POS      (0)
#define _OS_TIMER16_POS     (_OS_TIMER8_POS  + OS_TIMERS8)
#define _OS_TIMER24_POS     (_OS_TIMER16_POS + OS_TIMERS16)
#define _OS_TIMER32_POS     (_OS_TIMER24_POS + OS_TIMERS24)


#define OS_TIMERS           (OS_TIMERS8 + OS_TIMERS16 + OS_TIMERS24 + OS_TIMERS32)

#if OS_STIMERS > 0
    #define OS_ENABLE_STIMERS
#endif



/*--------------------------------------------------*/
/* Enable system timer if any type of timers used   */
/*--------------------------------------------------*/

#if defined(OS_ENABLE_DTIMERS)  ||  \
    defined(OS_ENABLE_TTIMERS)  ||  \
    defined(OS_ENABLE_STIMERS)  ||  \
    (OS_TIMERS > 0)

    #define OS_ENABLE_OS_TIMER
#endif




//------------------------------------------------------------------------------









/*
 ************************************************************************************************
 *                                                                                              *
 *  Defining integer types for all compilers.                                                   *
 *                                                                                              *
 *  This types used in system functions.                                                        *
 *                                                                                              *
 *  _OS_INT_TYPE - integer type of specified controller RAM cell size                           *
 *  _OS_INT_MASK - mask for bit addressing in _OS_INT_TYPE                                      *
 *  _OS_INT_SHIFT - size of _OS_INT_MASK                                                        *
 *  _OS_INT_SIZE - size of _OS_INT_TYPE in bits                                                 *
 *                                                                                              *
 ************************************************************************************************
 */

#ifdef __OSACCS18__
    #define __osa_uint8     unsigned int8
    #define __osa_uint16    unsigned int16
    #define __osa_uint32    unsigned int32
#else
    typedef unsigned char    __osa_uint8;
    typedef unsigned int     __osa_uint16;
    typedef unsigned long    __osa_uint32;
#endif


#ifdef __OSA30__
    typedef __osa_uint16    _OST_INT_TYPE;
    #define _OST_INT_MASK   15
    #define _OST_INT_SHIFT  4
    #define _OST_INT_SIZE   16
#else
    typedef __osa_uint8     _OST_INT_TYPE;
    #define _OST_INT_MASK    7
    #define _OST_INT_SHIFT   3
    #define _OST_INT_SIZE    8
#endif






/*
 ************************************************************************************************
 *                                                                                              *
 *  DEFINE BANKS TO ALLOCATE DATA                                                               *
 *                                                                                              *
 ************************************************************************************************
 */

/*------------------------------------------*/
/* Check for old style defitions            */
/*------------------------------------------*/
#if     defined(OS_BANK) ||                 \
        defined(OS_TASKS_BANK)  ||          \
        defined(OS_TIMERS_BANK)  ||         \
        defined(OS_TIMERS8_BANK)  ||        \
        defined(OS_TIMERS16_BANK)  ||       \
        defined(OS_TIMERS24_BANK)  ||       \
        defined(OS_TIMERS32_BANK)  ||       \
        defined(OS_TIMEOUTS_BANK)  ||       \
        defined(OS_BSEM_BANK)

#error "OSA error #2: Constants OS_xxx_BANK are not allowed now (use OS_BANK_xxx instead)"
        /* See manual section "Appendix/Error codes" for more information*/

#endif



/*------------------------------------------*/
/*                                          */
/* Set RAM bank constants                   */
/*                                          */
/*------------------------------------------*/

#ifndef OS_BANK_OS
#define OS_BANK_OS      0               /* RAM bank for OSA internal variables  */
#endif


#if defined(OS_BANK_TASK) && !defined(OS_BANK_TASKS)
#define OS_BANK_TASKS   OS_BANK_TASK
#endif


#ifndef OS_BANK_TASKS
#define OS_BANK_TASKS       OS_BANK_OS  /* RAM bank for task descriptors        */
#endif

#ifndef OS_BANK_TIMERS
#define OS_BANK_TIMERS      OS_BANK_OS  /* RAM bank for old style static timers */
#endif

#ifndef OS_BANK_TIMERS8
#define OS_BANK_TIMERS8     OS_BANK_TIMERS
#endif

#ifndef OS_BANK_TIMERS16
#define OS_BANK_TIMERS16    OS_BANK_TIMERS
#endif

#ifndef OS_BANK_TIMERS24
#define OS_BANK_TIMERS24    OS_BANK_TIMERS
#endif

#ifndef OS_BANK_TIMERS32
#define OS_BANK_TIMERS32    OS_BANK_TIMERS
#endif

#ifndef OS_BANK_TIMEOUTS
#define OS_BANK_TIMEOUTS    OS_BANK_TIMERS
#endif

#ifndef OS_BANK_STIMERS
#define OS_BANK_STIMERS     OS_BANK_TIMERS  /* RAM bank for static timers       */
#endif

#if defined(OS_BANK_BSEMS) && !defined(OS_BANK_BSEM)
#define OS_BANK_BSEM   OS_BANK_BSEMS
#endif

#ifndef OS_BANK_BSEM
#define OS_BANK_BSEM      OS_BANK_OS /* RAM bank for array of binary semaphores */
#endif






/*
 ************************************************************************************************
 *                                                                                              *
 *  Definition of keywords to allocate data for different compilers                             *
 *                                                                                              *
 ************************************************************************************************
 */

//------------------------------------------------------------------------------

#if defined(__OSAPICC18__)

    #define NEAR    near
    #define bank0   near
    #define bank1   bdata
    #define bank2   bdata
    #define bank3   bdata
    #define __osa30_near
    #define _OS_CUR_FLAGS_IN_OS_state   // Work with tasks state througth OS_state variable

#endif

//------------------------------------------------------------------------------

#if defined (__OSAMCC18__)

    #define NEAR    near
    #define bank0   near
    #define bank1
    #define bank2
    #define bank3
    #define bit     _OST_INT_TYPE
    #define __osa30_near
    #define _OS_CUR_FLAGS_IN_FSR        // Work with tasks state througth FSR

#endif

//------------------------------------------------------------------------------

#if defined (__OSAMCC30__)

    #define NEAR
    #define bank0
    #define bank1
    #define bank2
    #define bank3
    #define bit             _OST_INT_TYPE
    #define __osa30_near    __attribute__((near))
    #define _OS_CUR_FLAGS_IN_OS_state   // Work with tasks state througth OS_state variable

#endif

//------------------------------------------------------------------------------

#if defined (__OSACCS18__)

    #define NEAR
    #define bank0
    #define bank1
    #define bank2
    #define bank3
    #define bit     _OST_INT_TYPE
    #define __osa30_near
    #define _OS_CUR_FLAGS_IN_FSR        // Work with tasks state througth FSR

#endif

//------------------------------------------------------------------------------

#if defined(__OSAPICC__)

    #define NEAR    near
    #define bank0   near
    #define __osa30_near
    #define _OS_CUR_FLAGS_IN_FSR        // Work with tasks state througth FSR

#endif

//------------------------------------------------------------------------------

#if defined(__OSAPICC12__)

    #define NEAR    near
    #define bank0   near
    #define __osa30_near
    #define _OS_CUR_FLAGS_IN_OS_state   // Work with tasks state througth OS_state variable

#endif
//------------------------------------------------------------------------------


/*
 *------------------------------------------------------------------*
 *                                                                  *
 * Checking validness of bank settings for each type of OSA data    *
 *                                                                  *
 *------------------------------------------------------------------*
 */

#if   OS_BANK_OS == 0
    #define OS_BANK bank0
#elif OS_BANK_OS == 1
    #define OS_BANK bank1
#elif OS_BANK_OS == 2
    #define OS_BANK bank2
#elif OS_BANK_OS == 3
    #define OS_BANK bank3
#else
    #error  "OSA error #3: Incorrect OS_BANK_OS value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TASKS == 0
    #define OS_TASKS_BANK bank0
#elif OS_BANK_TASKS == 1
    #define OS_TASKS_BANK bank1
#elif OS_BANK_TASKS == 2
    #define OS_TASKS_BANK bank2
#elif OS_BANK_TASKS == 3
    #define OS_TASKS_BANK bank3
#else
    #error  "OSA error #4: Incorrect OS_BANK_TASKS value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMERS == 0
    #define OS_TIMERS_BANK bank0
#elif OS_BANK_TIMERS == 1
    #define OS_TIMERS_BANK bank1
#elif OS_BANK_TIMERS == 2
    #define OS_TIMERS_BANK bank2
#elif OS_BANK_TIMERS == 3
    #define OS_TIMERS_BANK bank3
#else
    #error  "OSA error #5: Incorrect OS_BANK_TIMERS value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_STIMERS == 0
    #define OS_STIMERS_BANK bank0
#elif OS_BANK_STIMERS == 1
    #define OS_STIMERS_BANK bank1
#elif OS_BANK_STIMERS == 2
    #define OS_STIMERS_BANK bank2
#elif OS_BANK_STIMERS == 3
    #define OS_STIMERS_BANK bank3
#else
    #error  "OSA error #6: Incorrect OS_BANK_STIMERS value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMERS8 == 0
    #define OS_TIMERS8_BANK bank0
#elif OS_BANK_TIMERS8 == 1
    #define OS_TIMERS8_BANK bank1
#elif OS_BANK_TIMERS8 == 2
    #define OS_TIMERS8_BANK bank2
#elif OS_BANK_TIMERS8 == 3
    #define OS_TIMERS8_BANK bank3
#else
    #error  "OSA error #7: Incorrect OS_BANK_TIMERS8 value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMERS16 == 0
    #define OS_TIMERS16_BANK bank0
#elif OS_BANK_TIMERS16 == 1
    #define OS_TIMERS16_BANK bank1
#elif OS_BANK_TIMERS16 == 2
    #define OS_TIMERS16_BANK bank2
#elif OS_BANK_TIMERS16 == 3
    #define OS_TIMERS16_BANK bank3
#else
    #error  "OSA error #8: Incorrect OS_BANK_TIMERS16 value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMERS24 == 0
    #define OS_TIMERS24_BANK bank0
#elif OS_BANK_TIMERS24 == 1
    #define OS_TIMERS24_BANK bank1
#elif OS_BANK_TIMERS24 == 2
    #define OS_TIMERS24_BANK bank2
#elif OS_BANK_TIMERS24 == 3
    #define OS_TIMERS24_BANK bank3
#else
    #error  "OSA error #9: Incorrect OS_BANK_TIMERS24 value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMERS32 == 0
    #define OS_TIMERS32_BANK bank0
#elif OS_BANK_TIMERS32 == 1
    #define OS_TIMERS32_BANK bank1
#elif OS_BANK_TIMERS32 == 2
    #define OS_TIMERS32_BANK bank2
#elif OS_BANK_TIMERS32 == 3
    #define OS_TIMERS32_BANK bank3
#else
    #error  "OSA error #10: Incorrect OS_BANK_TIMERS32 value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_TIMEOUTS == 0
    #define OS_TIMEOUTS_BANK bank0
#elif OS_BANK_TIMEOUTS == 1
    #define OS_TIMEOUTS_BANK bank1
#elif OS_BANK_TIMEOUTS == 2
    #define OS_TIMEOUTS_BANK bank2
#elif OS_BANK_TIMEOUTS == 3
    #define OS_TIMEOUTS_BANK bank3
#else
    #error  "OSA error #11: Incorrect OS_BANK_TIMEOUTS value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------

#if   OS_BANK_BSEM == 0
    #define OS_BSEM_BANK bank0
#elif OS_BANK_BSEM == 1
    #define OS_BSEM_BANK bank1
#elif OS_BANK_BSEM == 2
    #define OS_BSEM_BANK bank2
#elif OS_BANK_BSEM == 3
    #define OS_BSEM_BANK bank3
#else
    #error  "OSA error #12: Incorrect OS_BANK_BSEM value (should be 0, 1, 2 or 3)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif

//------------------------------------------------------------------------------
















/*
 ************************************************************************************************
 *                                                                                              *
 *  Definition of data sizes for each type of OSA data                                          *
 *                                                                                              *
 ************************************************************************************************
 */


/*
 *--------------------------------------*
 *                                      *
 *  Number of task descriptors          *
 *  (maximum active tasks at one time)  *                                                                           *
 *                                      *
 *--------------------------------------*
 */

#if OS_TASKS == 0
    #undef OS_TASKS
#endif

#if !defined(OS_TASKS)
    #define OS_TASKS    1       // We need at least 1 task
#endif






/*
 *--------------------------------------*
 *                                      *
 *  Types of timers                     *
 *                                      *
 *--------------------------------------*
 */

#if defined(OST_TIMER)
#error "OSA error #13: OST_TlMER is not supported! Use OS_TIMER_SIZE instead (see manual)"
        /* See manual section "Appendix/Error codes" for more information*/
#endif

#if !defined(OS_TIMER_SIZE)
    #define OS_TIMER_SIZE   2           /* Default timer size   */
#endif

#if   OS_TIMER_SIZE == 1
    #define OST_TIMER __osa_uint8
#elif OS_TIMER_SIZE == 2
    #define OST_TIMER __osa_uint16
#elif OS_TIMER_SIZE == 4
    #define OST_TIMER __osa_uint32
#else
    #error "OSA error #17: Bad TIMER size (must be 1, 2 or 4)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif


/*
 *--------------------------------------*
 * Size of static timer's counter       *
 *--------------------------------------*
 */

#if !defined(OS_STIMER_SIZE)
    #define OS_STIMER_SIZE  OS_TIMER_SIZE
#endif

#if   OS_STIMER_SIZE == 1
    #define _OST_STIMER __osa_uint8
#elif OS_STIMER_SIZE == 2
    #define _OST_STIMER __osa_uint16
#elif OS_STIMER_SIZE == 4
    #define _OST_STIMER __osa_uint32
#else
    #error "OSA error #18: Bad STIMER size (must be 1, 2 or 4)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif


/*
 *--------------------------------------*
 * Size of dynamic timer's counter      *
 *--------------------------------------*
 */

#ifdef OS_PTIMER_SIZE        // Redefine old name (ptimer) to new (dtimer)
    #define OS_DTIMER_SIZE OS_PTIMER_SIZE
#endif

#if !defined(OS_DTIMER_SIZE)
    #define OS_DTIMER_SIZE  OS_TIMER_SIZE
#endif

#if   OS_DTIMER_SIZE == 1
    #define _OST_DTIMER __osa_uint8
#elif OS_DTIMER_SIZE == 2
    #define _OST_DTIMER __osa_uint16
#elif OS_DTIMER_SIZE == 4
    #define _OST_DTIMER __osa_uint32
#else
    #error "OSA error #19: Bad DTIMER size (must be 1, 2 or 4)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif


/*
 *--------------------------------------*
 * Size of task timer's counter         *
 *--------------------------------------*
 */

#if !defined(OS_TTIMER_SIZE)
    #define OS_TTIMER_SIZE  OS_TIMER_SIZE
#endif

#if   OS_TTIMER_SIZE == 1
    #define _OST_TTIMER __osa_uint8
#elif OS_TTIMER_SIZE == 2
    #define _OST_TTIMER __osa_uint16
#elif OS_TTIMER_SIZE == 4
    #define _OST_TTIMER __osa_uint32
#else
    #error "OSA error #20: Bad TTIMER size (must be 1, 2 or 4)"
            /* See manual section "Appendix/Error codes" for more information*/
#endif





























/*
 ************************************************************************************************
 *                                                                                              *
 *  S Y S T E M   D A T A   T Y P E S                                                           *
 *                                                                                              *
 ************************************************************************************************
 */



/*
 *------------------------------------------*
 *  Simple byte message                     *
 * (this type should be defined BEFORE      *
 * including port\osa_xxx.h)                *
 *------------------------------------------*
 */


#ifdef  OST_SMSG
#error "OSA error #14: Can't redefine name OST SMSG in 'OSAcfg.h'. Use OST_SMSG instead."
        /* See manual section "Appendix/Error codes" for more information*/
#endif

#if !defined(OS_SMSG_TYPE)
#define     OS_SMSG_TYPE    unsigned char
#endif

typedef     OS_SMSG_TYPE    OST_SMSG;







/***********************************************/
/* INCLUDE PROCESSOR SPECIFIC DEFINITIONS      */
/***********************************************/

#if defined(__OSAPICC18__)
    #include "port\osa_picc18.h"         // HT-PICC18
#elif defined(__OSAMCC18__)
    #include "port\osa_mcc18.h"          // MPLAB C18
#elif defined(__OSAMCC30__)
    #include "port\osa_mcc30.h"          // MPLAB C30
#elif defined(__OSACCS18__)
    #include "port\osa_ccs18.h"          // CCS-PICC (for PIC18 only)
#elif defined(__OSAPICC12__)
    #include "port\osa_picc12.h"         // HT_PICC for 12-bit PICs
#elif defined(__OSAPICC__)
    #include "port\osa_picc16.h"         // HT_PICC
#else
    #error "OSA error #1: Unknown compiler!"
            /* See manual section "Appendix/Error codes" for more information*/
#endif


/*
 *----------------------------------------------*
 *  Pointer to message                          *
 *----------------------------------------------*
 */
#ifdef  OST_MSG
#error "OSA error #15: Can't redefine name OST MSG in 'OSAcfg.h'. Use OST_MSG instead."
        /* See manual section "Appendix/Error codes" for more information*/
#endif

#if !defined(OS_MSG_TYPE)
#define OS_MSG_TYPE   void *
#endif

typedef OS_MSG_TYPE    OST_MSG;







/*
 *----------------------------------------------*
 *  Pointer to message descriptor               *
 *----------------------------------------------*
 */

typedef struct _OST_MSG_CB
{
   _OST_INT_TYPE    status;     // State (=1 - busy / =0 - free)
    OST_MSG         msg;        // Pointer to message body
} OST_MSG_CB;





/*
 *----------------------------------------------*
 *  Message's queues                            *
 *----------------------------------------------*
 */

/*--- Queue's control block                         ---*/

typedef struct
{
    _OST_INT_TYPE   cSize;      // Queue size
    _OST_INT_TYPE   cFilled;    // Number of filled elements
    _OST_INT_TYPE   cBegin;     // First element in buffer
} OST_QUEUE_CONTROL;


/*--- Descriptor of queue of pointers to messages   ---*/

typedef struct
{
    OST_QUEUE_CONTROL Q;
    OST_MSG *pMsg;              // Pointer to queue buffer
} OST_QUEUE;


/*--- Descriptor of queue of simple messages        ---*/

typedef struct
{
    OST_QUEUE_CONTROL Q;
    OST_SMSG *pSMsg;            // Pointer to queue buffer
} OST_SQUEUE;



/*
 *----------------------------------------------*
 *  Flags                                       *
 *----------------------------------------------*
 */

#define OST_FLAG    __osa_uint8
#define OST_FLAG8   __osa_uint8
#define OST_FLAG16  __osa_uint16
#define OST_FLAG32  __osa_uint32








/*
 *--------------------------------------------------------------*
 *                                                              *
 *  System state flags                                          *
 *                                                              *
 *  !Do not change positions of theese bits.                    *
 *  For MCC30 bits cIPL_Temp must occupy 5, 6 and 7 positions   *
 *                                                              *
 *--------------------------------------------------------------*
 */

typedef struct
{
    /*0*/   _OST_INT_TYPE   bEventError        : 1; // Event error
    /*1*/   _OST_INT_TYPE   bError             : 1; // Task create error
    /*2*/   _OST_INT_TYPE   bInCriticalSection : 1; // One of task is in critical
                                                    // section
    /*3*/   _OST_INT_TYPE   bCheckingTasks     : 1; // OS_Sched:
                                                    //   =1 - best task searching
                                                    //   =0 - best task executed
    /*4*/   _OST_INT_TYPE   bBestTaskFound     : 1; // OS_Sched: Best task found


    //------------------------------------------------------------------------------
    // Processor specified bits
    //------------------------------------------------------------------------------
    #if     defined(__OSA12__)
    //------------------------------------------------------------------------------

        /*5*/   _OST_INT_TYPE   bTimeout    : 1; // Event waiting timeout
        /*6*/   _OST_INT_TYPE   bUser0      : 1; // For PIC12: Two user purpose bits
        /*7*/   _OST_INT_TYPE   bUser1      : 1; // For PIC12: Two user purpose bits

    //------------------------------------------------------------------------------
    #elif   defined(__OSA16__)
    //------------------------------------------------------------------------------

        /*5*/   _OST_INT_TYPE   bTimeout    : 1; // Event waiting timeout
        /*6*/   _OST_INT_TYPE   bGIE_CTemp  : 1; // Saved GIE while in critical section

    //------------------------------------------------------------------------------
    #elif   defined(__OSA18__)
    //------------------------------------------------------------------------------

        /*5*/   _OST_INT_TYPE   bTimeout    : 1; // Event waiting timeout
        /*6*/   _OST_INT_TYPE   bGIE_CTemp  : 1; // Saved GIEH while in critical section
        /*7*/   _OST_INT_TYPE   bGIEL_CTemp : 1; // Saved GIEL while in critical section

    //------------------------------------------------------------------------------
    #elif   defined(__OSAMCC30__)
    //------------------------------------------------------------------------------

        /*5..7*/_OST_INT_TYPE   cIPL_Temp   : 3; // Saved InterruptPriotityLevel
                                                 // when entering critical section

        /*8*/   _OST_INT_TYPE   bTimeout    : 1; // Event waiting timeout

        /*
         *------------------------------------------------------*
         *  Tells that task was replaced (with OS_Task_Replace) *
         *  so we don't need to save stack pointer for MCC30    *
         *------------------------------------------------------*
         */

        /*9*/   _OST_INT_TYPE   bTaskReplaced                   : 1;


         /*
          *-----------------------------------------------------*
          * Theese 5 bit variables contains information         *
          * about enablity "lnk" instruction in the             *
          * begin of 5 switching context routines.              *
          *-----------------------------------------------------*
          */

        /*10*/  _OST_INT_TYPE   bOSRetPoint_LNK                 : 1;
        /*11*/  _OST_INT_TYPE   bOSRetPointNoSave_LNK           : 1;
        /*12*/  _OST_INT_TYPE   bOSClearReady_LNK               : 1;
        /*13*/  _OST_INT_TYPE   bOSClearReadySetCanContinue_LNK : 1;
        /*14*/  _OST_INT_TYPE   bOSCheckEvent_LNK               : 1;

    //------------------------------------------------------------------------------
    #endif
    //------------------------------------------------------------------------------


} OST_SYSTEM_FLAGS;






/*
 *--------------------------------------------------------------*
 *                                                              *
 *  Task state flags                                            *
 *                                                              *
 *  !Do not change placement of theese bits                     *
 *                                                              *
 *--------------------------------------------------------------*
 */

typedef struct
{
    /*0..2*/_OST_INT_TYPE   cPriority   : 3;    // Task priority (0..7)
    /*3*/   _OST_INT_TYPE   bReady      : 1;    // Ready to execute
    /*4*/   _OST_INT_TYPE   bDelay      : 1;    // Timer active: OS_Delay (bCanContinue=0)
                                                // or event waiting with timeout (bCanContinue=1)

    /*5*/   _OST_INT_TYPE   bCanContinue: 1;    // Can continue, while bDelay flag is set
    /*6*/   _OST_INT_TYPE   bEnable     : 1;    // Descriptor is busy by task
    /*7*/   _OST_INT_TYPE   bPaused     : 1;    // Task paused (it is still active, but can
                                                // became ready only from extenal task)
} OST_TASK_STATE;





/*
 *--------------------------------------------------------------*
 *                                                              *
 *  Task control block                                          *
 *                                                              *
 *--------------------------------------------------------------*
 */

typedef struct
{
    OST_TASK_STATE      State;              // Current task state
    OST_CODE_POINTER    pTaskPointer;       // ROM pointer

    #ifdef __OSA18__
        unsigned char   cTempFSR1;          // Saved FSR1 (for MCC18)
    #endif

    #ifdef __OSA30__                        // W registers
        __osa_uint16    W8_Temp;
        __osa_uint16    W9_Temp;
        __osa_uint16    W10_Temp;
        __osa_uint16    W11_Temp;
        __osa_uint16    W12_Temp;
        __osa_uint16    W13_Temp;
        __osa_uint16    W14_Temp;
        __osa_uint16    W15_Temp;
    #endif

    #ifdef OS_ENABLE_TTIMERS
        _OST_TTIMER     Timer;                  // Timer counter for delays
    #endif

} OST_TCB;   // Task Control Block


typedef OS_TASKS_BANK OST_TCB *     OST_TASK_POINTER;



#define OS_WORST_PRIORITY       7       // Lowest priority
#define OS_BEST_PRIORITY        0       // Highest priority







/*
 *--------------------------------------------------------------*
 *                                                              *
 *  Dynamic timers                                              *
 *                                                              *
 *--------------------------------------------------------------*
 */

//---------------------------------------------------------------
#ifdef OS_ENABLE_DTIMERS
//---------------------------------------------------------------

    /*
     *------------------------------------------*
     *                                          *
     *  Dynamic timer's state flags             *
     *                                          *
     *  !Do not change placement of variables   *
     *                                          *
     *------------------------------------------*
     */

    typedef struct
    {
        _OST_INT_TYPE   bTimeout    : 1;    // Overflow occured
        _OST_INT_TYPE   bActive     : 1;    // Timer is active (was created by OS_Dtimer_Create)
                                            // (For system variable _OS_DTimers.Flags allways = 1)

        _OST_INT_TYPE   bRun        : 1;    // = 1 - Timer is counnting
                                            // = 0 - Timer is stopped

        _OST_INT_TYPE   bNextEnable : 1;    // = 0 - last timer in list,
                                            // = 1 - there is next timer
    } OST_DTIMER_FLAGS;


    /*
     *------------------------------------------*
     *                                          *
     *  Header of list of dynamic timers        *
     *                                          *
     *------------------------------------------*
     */

    typedef struct
    {
        OST_DTIMER_FLAGS Flags;
        void *           Next;          // Pointer to first timer in list
    } OST_DTIMER_CB;

    /*
     *------------------------------------------*
     *                                          *
     *  Dynamic timer's control block           *
     *                                          *
     *------------------------------------------*
     */

    typedef struct
    {
        OST_DTIMER_FLAGS Flags;         // Timer's state flags
        void *           Next;          // Pointer to next timer in list
        _OST_DTIMER      Timer;         // Counter
    } OST_DTIMER;

//---------------------------------------------------------------
#endif  // OS_ENABLE_DTIMERS
//---------------------------------------------------------------














/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA system variables prototypes                                                             *
 *                                                                                              *
 ************************************************************************************************
 */


#define OST_TASK_POINTER     OST_TASK_POINTER    // OST_TASK_POINTER defined in
                                                // file "port\osa_xxx.h" for
                                                // each compiler


extern  NEAR        OST_SYSTEM_FLAGS            OS_Flags        __osa30_near;


/*
 *--------------------------------------------------------------*
 *  Addition temp variable. In some system services             *
 *  used for saving GIE                                         *
 *--------------------------------------------------------------*
 */
extern  NEAR        _OST_INT_TYPE               _OS_temp        __osa30_near;



//------------------------------------------------------------------------------
#ifndef __OSA12__
/*
 *--------------------------------------------------------------*
 *  Addition temp variable for all except PICC12                *
 *--------------------------------------------------------------*
 */
extern  NEAR        _OST_INT_TYPE               _OS_tempH       __osa30_near;
#endif
//------------------------------------------------------------------------------



#if defined(_OS_CUR_FLAGS_IN_OS_state)
/*
 *--------------------------------------------------------------*
 *  Work with task state making through this variable           *
 *--------------------------------------------------------------*
 */
extern  NEAR        OST_TASK_STATE              OS_state        __osa30_near;
#endif


/*
 *--------------------------------------------------------------*
 *  Pointer to current task                                     *
 *--------------------------------------------------------------*
 */
extern              OST_TASK_POINTER    NEAR    _OS_CurTask     __osa30_near;



//------------------------------------------------------------------------------
#if !defined(OS_DISABLE_PRIORITY)
/*
 *--------------------------------------------------------------*
 *  Priority motinoring variables:                              *
 *      - best priority while searching best task               *
 *      - Pointer to best task                                  *
 *      - Pointer to lase executed task                         *
 *--------------------------------------------------------------*
 */
extern  OS_BANK     _OST_INT_TYPE               _OS_best_priority   __osa30_near;
extern              OST_TASK_POINTER    OS_BANK _OS_BestTask        __osa30_near;
extern              OST_TASK_POINTER    OS_BANK _OS_LastTask        __osa30_near;

#endif
//------------------------------------------------------------------------------


/*
 *--------------------------------------------------------------*
 *  Array of task descriptors                                   *
 *--------------------------------------------------------------*
 */
extern OS_TASKS_BANK    OST_TCB                 OS_TaskVars[OS_TASKS] __osa30_near;


//------------------------------------------------------------------------------
#if OS_TIMERS24 > 0
/*
 *--------------------------------------------------------------*
 *  Prescaler for 24-bit old style static timers                *
 *--------------------------------------------------------------*
 */
extern OS_BANK      _OST_INT_TYPE               OS_Ticks            __osa30_near;
#endif
//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
#ifdef OS_ENABLE_DTIMERS
/*
 *--------------------------------------------------------------*
 *  Pointer to list of dynamic timers                           *
 *--------------------------------------------------------------*
 */
extern OS_BANK      OST_DTIMER_CB               _OS_DTimers         __osa30_near;

    #if defined(__OSAMCC30__)
        /*-------------------------------------------------------------
         * For work with list in interrupt
         */
        extern OS_BANK OST_DTIMER               *_OS_DTimerWork     __osa30_near;
    #endif
#endif
//------------------------------------------------------------------------------



/*
 *--------------------------------------------------------------*
 *  Old style static timers                                     *
 *--------------------------------------------------------------*
 */

#if OS_TIMERS > 0
    extern  OS_TIMEOUTS_BANK    _OST_INT_TYPE   OS_Timeouts[]   __osa30_near;
#endif

#if OS_TIMERS32 > 0
    extern  OS_TIMERS32_BANK    __osa_uint32    OS_Timers32[]   __osa30_near;
#endif

#if OS_TIMERS24 > 0
    extern  OS_TIMERS24_BANK    __osa_uint16    OS_Timers24[]   __osa30_near;
#endif

#if OS_TIMERS16 > 0
    extern  OS_TIMERS16_BANK    __osa_uint16    OS_Timers16[]   __osa30_near;
#endif

#if OS_TIMERS8  > 0
    extern  OS_TIMERS8_BANK     __osa_uint8     OS_Timers8[]    __osa30_near;
#endif



/*
 *--------------------------------------------------------------*
 *  Static timers                                               *
 *--------------------------------------------------------------*
 */
#if OS_STIMERS > 0
    extern  OS_STIMERS_BANK     _OST_STIMER     OS_STimers[]    __osa30_near;
#endif


/*
 *--------------------------------------------------------------*
 *  Binary semaphores                                           *
 *--------------------------------------------------------------*
 */

#ifndef OS_BSEMS
    #define OS_BSEMS    0
#endif

#if OS_BSEMS > 0
    extern  OS_BSEM_BANK        _OST_INT_TYPE   OS_BSems[]      __osa30_near;
#endif






/*
 *--------------------------------------------------------------*
 *  Counting semaphores                                         *
 *--------------------------------------------------------------*
 */
#ifdef OS_ENABLE_CSEM

    #if !defined(OS_CSEM_SIZE)
        #define OS_CSEM_SIZE    1
    #endif

    #if     OS_CSEM_SIZE == 1
        typedef __osa_uint8 OST_CSEM;
    #elif   OS_CSEM_SIZE == 2
        typedef __osa_uint16 OST_CSEM;
    #elif   OS_CSEM_SIZE == 4
        typedef __osa_uint32 OST_CSEM;
    #else
        #error "OSA error #16: Incorrect OS_CSEM_SIZE value (m.b. only 1, 2 or 4)! (see OSAcfg.h)"
                /* See manual section "Appendix/Error codes" for more information*/
    #endif

    extern void _OS_Csem_Signal(OST_CSEM *pCSem);

#endif

#if !defined(OS_CSEM_SIZE)
    #define OS_CSEM_SIZE    0
#endif


















/*
 ************************************************************************************************
 *                                                                                              *
 *  Internal system functions prototypes                                                        *
 *                                                                                              *
 ************************************************************************************************
 */


#ifdef OS_ENABLE_TTIMERS
    extern void _OS_InitDelay(_OST_TTIMER Delay);
#endif

//------------------------------------------------------------------------------

#ifdef OS_ENABLE_OS_TIMER

    #ifndef OS_USE_INLINE_TIMER
        extern void OS_Timer (void);
    #else
        #define OS_Timer()  __OS_TimerInline(0)
    #endif

#endif

//------------------------------------------------------------------------------

#ifdef OS_ENABLE_DTIMERS

    void _OS_Dtimer_Create (OST_DTIMER *dtimer);
    void _OS_Dtimer_Delete (OST_DTIMER *dtimer);
    #define OS_Dtimer_Create(dtimer)     _OS_Dtimer_Create(&dtimer)
    #define OS_Dtimer_Delete(dtimer)     _OS_Dtimer_Delete(&dtimer)

#endif

//------------------------------------------------------------------------------

extern void _OS_Task_Create(_OST_INT_TYPE priority, OST_CODE_POINTER TaskAddr);

//------------------------------------------------------------------------------
// System variables initialization
extern void  OS_Init (void);


//------------------------------------------------------------------------------
// Critical sections
extern void OS_EnterCriticalSection (void);
extern void OS_LeaveCriticalSection (void);



//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
#define OS_WAIT_NO_TIMEOUT          0
#define OS_TASK_ENABLED             1
#define OS_TASK_DISABLED            0
















/*
 ************************************************************************************************
 *                                                                                              *
 *  Internal macro for work with state flags                                                    *
 *                                                                                              *
 ************************************************************************************************
*/


#if defined(_OS_CUR_FLAGS_IN_OS_state)

    // For PICC12, PICC18 and MCC30

    #define _OS_bTaskReady              OS_state.bReady
    #define _OS_bTaskCanContinue        OS_state.bCanContinue
    #define _OS_bTaskDelay              OS_state.bDelay
    #define _OS_bTaskTimeout            (!OS_state.bDelay)
    #define _OS_bTaskEnable             OS_state.bEnable
    #define _OS_cTaskPriority           OS_state.cPriority
    #define _OS_bTaskPaused             OS_state.bPaused

#elif defined(__OSACCS18__)

    // For CCS

    #define _OS_bTaskReady              ((OST_TASK_STATE)_indf).bReady
    #define _OS_bTaskCanContinue        ((OST_TASK_STATE)_indf).bCanContinue
    #define _OS_bTaskDelay              ((OST_TASK_STATE)_indf).bDelay
    #define _OS_bTaskTimeout            (!(((OST_TASK_STATE)_indf).bDelay))
    #define _OS_bTaskEnable             ((OST_TASK_STATE)_indf).bEnable
    #define _OS_cTaskPriority           ((OST_TASK_STATE)_indf).cPriority
    #define _OS_bTaskPaused             ((OST_TASK_STATE)_indf).bPaused

#else

    // For MCC18 and PICC16

    #define _OS_bTaskReady              ((near OST_TASK_STATE*)(&_indf))->bReady
    #define _OS_bTaskCanContinue        ((near OST_TASK_STATE*)(&_indf))->bCanContinue
    #define _OS_bTaskDelay              ((near OST_TASK_STATE*)(&_indf))->bDelay
    #define _OS_bTaskTimeout            (!((near OST_TASK_STATE*)(&_indf))->bDelay)
    #define _OS_bTaskEnable             ((near OST_TASK_STATE*)(&_indf))->bEnable
    #define _OS_cTaskPriority           ((near OST_TASK_STATE*)(&_indf))->cPriority
    #define _OS_bTaskPaused             ((near OST_TASK_STATE*)(&_indf))->bPaused

#endif






/*
 ************************************************************************************************
 *                                                                                              *
 *  Include definitions of services:                                                            *
 *                                                                                              *
 ************************************************************************************************
 */

//#include "service\osa_names.h"      // Table of alternate names
#include "service\osa_oldnames.h"   // Table of alternate names
#include "service\osa_system.h"     // System services
#include "service\osa_bsem.h"       // Binary semaphores
#include "service\osa_csem.h"       // Counting semaphores
#include "service\osa_flag.h"       // Flags
#include "service\osa_stimer.h"     // Static timers
#include "service\osa_stimer_old.h" // Old style static timers
#include "service\osa_dtimer.h"     // Dynamic timers
#include "service\osa_msg.h"        // Pointer to messages
#include "service\osa_queue.h"      // Queue of pointers to messages
#include "service\osa_squeue.h"     // Queue of simple messages
#include "service\osa_smsg.h"       // Simple messages
#include "service\osa_tasks.h"      // Tasks
#include "service\osa_timer.h"      // System timer






//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------















